home *** CD-ROM | disk | FTP | other *** search
/ Super PC 31 / Super PC 31 (Shareware).iso / spc / inter / speakf / fuente / rtpacket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-28  |  8.5 KB  |  334 lines

  1. /*
  2.  
  3.     RTP packet encoding and decoding routines
  4.  
  5. */
  6.  
  7. #include "netfone.h"
  8.  
  9. #ifdef RTP_SUPPORT
  10. typedef enum {
  11.     AE_PCMU, AE_PCMA, AE_G721, AE_IDVI, AE_G723, AE_GSM,
  12.     AE_1016, AE_LPC, 
  13.     AE_L8, AE_L16, AE_L24, AE_L32,
  14.     AE_G728, AE_TRUE,
  15.     AE_MAX
  16. } audio_encoding_t;
  17.  
  18. /* common audio description for files and workstation */
  19. typedef struct {
  20.     audio_encoding_t encoding;  /* type of encoding (differs) */
  21.     unsigned sample_rate;       /* sample frames per second */
  22.     unsigned channels;          /* number of interleaved channels */
  23. } audio_descr_t;
  24. #endif
  25.  
  26. #define bcopy(s, d, l)    _fmemcpy(d, s, l)
  27.  
  28. /*    RTP_MAKE_SDES  --  Generate a source description for this
  29.                        user, based either on information obtained
  30.                        from the password file or supplied by
  31.                        environment variables.  */
  32.  
  33. int rtp_make_sdes(char **pkt, unsigned long ssrc_i, int exact)
  34. {
  35.     char p[512];
  36.     rtcp_t *rp = (rtcp_t *) p;
  37.     char *ap;
  38.     int l;
  39.     char s[256];
  40.  
  41. #define addSDES(item, text) *ap++ = item; *ap++ = l = strlen(text); \
  42.                             bcopy(text, ap, l); ap += l
  43.  
  44. #ifdef REASONABLE
  45.     rp->common.version = RTP_VERSION;
  46.     rp->common.p = 0;
  47.     rp->common.count = 1;
  48.     rp->common.pt = RTCP_SDES;
  49. #else
  50.     *((short *) p) = (RTP_VERSION << 14) | RTCP_SDES | (1 << 8);
  51. #endif    
  52.     rp->r.sdes.src = ssrc_i;
  53.  
  54.     ap = (char *) rp->r.sdes.item;
  55.  
  56.     /* Build canonical name for this user.    This is generally
  57.        a name which can be used for "talk" and "finger", and
  58.        is not necessarily the user's E-mail address.  If the
  59.        exact flag is set, we precede the name with an asterisk
  60.        to inform the LWL server this name cannot be matched by
  61.        a wild card. */
  62.     
  63.     if (exact) {
  64.         s[0] = '*';
  65.         strcpy(s + 1, lwl_s_email);
  66.         addSDES(RTCP_SDES_CNAME, s);
  67.     } else {   
  68.         addSDES(RTCP_SDES_CNAME, lwl_s_email);
  69.     }
  70.     if (lwl_s_fullname[0]) {
  71.         addSDES(RTCP_SDES_NAME, lwl_s_fullname);
  72.     }
  73.     addSDES(RTCP_SDES_EMAIL, lwl_s_email);
  74.     if (lwl_s_phone[0]) {
  75.         addSDES(RTCP_SDES_PHONE, lwl_s_phone);
  76.     }
  77.     if (lwl_s_location[0]) {
  78.         addSDES(RTCP_SDES_LOC, lwl_s_location);
  79.     }
  80.  
  81.     addSDES(RTCP_SDES_TOOL, rstring(IDS_T_RTP_TOOL));
  82.  
  83.     /* Add a PRIV item indicating the port we're communicating on. */
  84.  
  85.     sprintf(s, Format(59), NETFONE_COMMAND_PORT);
  86.     addSDES(RTCP_SDES_PRIV, s);
  87.  
  88.     *ap++ = RTCP_SDES_END;
  89.     *ap++ = 0;
  90.  
  91.     l = ap - p;
  92.  
  93.     rp->common.length = ((l + 3) / 4) - 1;
  94.     l = (rp->common.length + 1) * 4;
  95.     *pkt = (char *) malloc(l);
  96.     if (*pkt == NULL) {
  97.         return 0;
  98.     }
  99.     revshort((short *) p);
  100.     revshort((short *) (p + 2));
  101.     bcopy(p, *pkt, l);
  102.     return l;
  103. }
  104.  
  105. /*  RTP_MAKE_BYE  --  Create a "BYE" RTCP packet for this connection.  */
  106.  
  107. int rtp_make_bye(char *p, unsigned long ssrc_i, char *raison)
  108. {
  109.     rtcp_t *rp = (rtcp_t *) p;
  110.     char *ap;
  111.     int l;
  112.  
  113. #ifdef REASONABLE
  114.     rp->common.version = RTP_VERSION;
  115.     rp->common.p = 0;
  116.     rp->common.count = 1;
  117.     rp->common.pt = RTCP_BYE;
  118. #else
  119.     *((short *) p) = (RTP_VERSION << 14) | RTCP_BYE | (1 << 8);
  120. #endif    
  121.     rp->r.bye.src[0] = ssrc_i;
  122.  
  123.     ap = (char *) rp->r.sdes.item;
  124.  
  125.     l = 0;
  126.     if (raison != NULL) {
  127.         l = strlen(raison);
  128.         if (l > 0) {
  129.             *ap++ = l;
  130.             bcopy(raison, ap, l);
  131.             ap += l;
  132.         }
  133.     }
  134.  
  135.     while ((ap - p) & 3) {
  136.         *ap++ = 0;
  137.     }
  138.     l = ap - p;
  139.  
  140.     rp->common.length = (l / 4) - 1;
  141.     l = (rp->common.length + 1) * 4;
  142.     revshort((short *) p);
  143.     revshort((short *) (p + 2));
  144.     return l;
  145. }
  146.  
  147. #ifdef RTP_SUPPORT
  148.  
  149. /*    RTPOUT    --    Convert a sound buffer into an RTP packet, given the
  150.                 SSRC, timestamp, and sequence number appropriate for the
  151.                 next packet sent to this connection.  */
  152.  
  153. LONG rtpout(soundbuf *sb, unsigned long ssrc_i,
  154.             unsigned long timestamp_i, unsigned short seq_i)
  155. {
  156.     soundbuf rp;
  157.     rtp_hdr_t *rh = (rtp_hdr_t *) &rp;
  158.     LONG pl = 0;
  159.  
  160.     rh->version = RTP_VERSION;
  161.     rh->p = 0;
  162.     rh->x = 0;
  163.     rh->cc = 0;
  164.     rh->m = 0;
  165.     rh->seq = seq_i;
  166.     rh->ts = timestamp_i;
  167.     rh->ssrc = ssrc_i;
  168.  
  169.     if (sb->compression & fCompGSM) {
  170.         rh->pt = 3;
  171.         bcopy(sb->buffer.buffer_val + 2, ((char *) &rp) + 12,
  172.                   (int) sb->buffer.buffer_len - 2);
  173.         pl = (sb->buffer.buffer_len - 2) + 12;
  174.  
  175.     } else if (sb->compression & fCompADPCM) {
  176.         rh->pt = 5;
  177.         bcopy(sb->buffer.buffer_val, ((char *) &rp) + 12 + 4,
  178.                   (int) sb->buffer.buffer_len - 3);
  179.         bcopy(sb->buffer.buffer_val + ((int) sb->buffer.buffer_len - 3),
  180.                   ((char *) &rp) + 12, 3);
  181.         ((char *) &rp)[15] = 0;
  182.         pl = (sb->buffer.buffer_len - 1) + 12;
  183.  
  184.     } else {    /* Uncompressed PCMU samples */
  185.         rh->pt = 0;
  186.         bcopy(sb->buffer.buffer_val, ((char *) &rp) + 12,
  187.                 (int) sb->buffer.buffer_len);
  188.         pl = (int) sb->buffer.buffer_len + 12;
  189.     }
  190.     if (pl > 0) {
  191.         bcopy((char *) &rp, (char *) sb, (int) pl);
  192.     }
  193.     return pl;
  194. }
  195.  
  196. audio_descr_t adt[] = {
  197. /* enc       sample ch */
  198.   {AE_PCMU,  8000, 1},    /*    0 PCMU */
  199.   {AE_MAX,     8000, 1},    /*    1 1016 */
  200.   {AE_G721,  8000, 1},    /*    2 G721 */
  201.   {AE_GSM,     8000, 1},    /*    3 GSM */
  202.   {AE_G723,  8000, 1},    /*    4 Unassigned */
  203.   {AE_IDVI,  8000, 1},    /*    5 DVI4 */
  204.   {AE_IDVI, 16000, 1},    /*    6 DVI4 */
  205.   {AE_LPC,     8000, 1},    /*    7 LPC */
  206.   {AE_MAX,        0, 1},    /*    8 PCMA */
  207.   {AE_MAX,        0, 1},    /*    9 G722 */
  208.   {AE_L16,    44100, 2},    /* 10 L16 */
  209.   {AE_L16,    44100, 1},    /* 11 L16 */
  210.   {AE_MAX,        0, 1},    /* 12 */
  211. };
  212.  
  213. #define MAX_MISORDER 100
  214. #define MAX_DROPOUT  3000
  215.  
  216. int isrtp(unsigned char *pkt, int len, struct connection *c)
  217. {
  218.     rtp_hdr_t *rh = (rtp_hdr_t *) pkt;
  219.  
  220. /*fprintf(stderr, "Ver = %d, pt = %d, p = %d, x = %d\n",
  221. rh->version, rh->pt, rh->p, rh->x); */
  222.  
  223.     if (rh->version == RTP_VERSION && /* Version ID correct */
  224.         rh->pt < ELEMENTS(adt) &&      /* Payload type credible */
  225.         adt[rh->pt].sample_rate != 0 && /* Defined payload type */
  226.                                       /* Padding, if present, is plausible */
  227.         (!rh->p || (pkt[len - 1] < (len - (12 + 4 * rh->cc)))) &&
  228.         !rh->x                          /* No extension present */
  229.        ) {
  230.         struct soundbuf sb;
  231.         unsigned char *payload;
  232.         int paylen;
  233.  
  234.         payload = pkt + (12 + 4 * rh->cc); /* Start of payload */
  235.         paylen = len - ((12 + 4 * rh->cc) +/* Length of payload */
  236.                     (rh->p ? pkt[len - 1] : 0));
  237.         sb.compression = 0;
  238.         sb.buffer.buffer_len = 0;
  239.  
  240.         /* Fake an RTP unique host name from the SSRC identifier. */
  241.  
  242.         sprintf(sb.sendinghost, Format(60),
  243.             pkt[8], pkt[9], pkt[10], pkt[11]);
  244.  
  245.         switch (adt[rh->pt].encoding) {
  246.  
  247.             case AE_PCMU:
  248.                 sb.buffer.buffer_len = paylen;
  249.                 bcopy(payload, sb.buffer.buffer_val, paylen);
  250.                 break;
  251.  
  252.             case AE_GSM:
  253.                 sb.buffer.buffer_len = paylen + sizeof(short);
  254.                 bcopy(payload, sb.buffer.buffer_val + 2, paylen);
  255.                 *((short *) sb.buffer.buffer_val) =
  256.                     (paylen * 160) / 33;
  257.                 sb.compression |= fCompGSM;
  258.                 break;
  259.  
  260.             case AE_IDVI:
  261.                 bcopy(payload + 4, sb.buffer.buffer_val, paylen - 4);
  262.                 sb.buffer.buffer_len = paylen - 1;
  263.                 bcopy(payload, sb.buffer.buffer_val + (paylen - 4), 3);
  264.                 sb.buffer.buffer_len = paylen - 1;
  265.                 if (adt[rh->pt].sample_rate == 8000) {
  266.                     sb.compression |= fCompADPCM;
  267.                 } else {
  268.  
  269.                     /* Bogus attempt to convert sampling rate.    We
  270.                        really need to do this in linear mode, which isn't
  271.                        supported on all SPARCs.  This is better than
  272.                        nothing, though. */
  273.  
  274.                     int inc = adt[rh->pt].sample_rate / 8000, i;
  275.                     unsigned char *in = (unsigned char *) sb.buffer.buffer_val,
  276.                                   *out = (unsigned char *) sb.buffer.buffer_val;
  277.  
  278.                     adpcmdecomp(&sb);
  279.                     for (i = 0; i < (paylen - 4) / inc; i++) {
  280.                         *out++ = *in;
  281.                         in += inc;
  282.                     }
  283.                     sb.buffer.buffer_len /= inc;
  284.                 }
  285.                 break;
  286.  
  287. #ifdef LPC_IMPLEMENTED
  288.             case AE_LPC:
  289.                 {
  290.                     lpc_synthesize((lpcparams_t *) payload, 1.0,
  291.                         (unsigned char *) sb.buffer.buffer_val);
  292.                     sb.buffer.buffer_len = 160;
  293.                 }
  294.                 break;
  295. #endif                
  296.  
  297.             case AE_L16:
  298.                 if (adt[rh->pt].channels == 1) {
  299.                     int i, j, k;
  300.                 
  301.                     for (i = j = k = 0; i < (paylen / 8); i++) {
  302.                         if ((k & 3) != 2  && ((i % 580) != 579)) {
  303.                             sb.buffer.buffer_val[j++] =
  304.                                 audio_s2u((((unsigned short *) payload)[i * 4]));
  305.                         }
  306.                         k = (k + 1) % 11;
  307.                     }
  308.                     sb.buffer.buffer_len = j;
  309.                 } else if (adt[rh->pt].channels == 2) {
  310.                     int i, j, k;
  311.                 
  312.                     for (i = j = k = 0; i < (paylen / 16); i++) {
  313.                         if ((k & 3) != 2  && ((i % 580) != 579)) {
  314.                             sb.buffer.buffer_val[j++] =
  315.                                 audio_s2u(((((unsigned short *) payload)[i * 8]) +
  316.                                            (((unsigned short *) payload)[i * 8 + 1])) / 2);
  317.                         }
  318.                         k = (k + 1) % 11;
  319.                     }
  320.                     sb.buffer.buffer_len = j;
  321.                 }
  322.                 break;
  323.  
  324.             default:
  325.                 /* Unknown compression type. */
  326.                 break;
  327.         }
  328.         bcopy(&sb, pkt, (int) (((sizeof sb - BUFL)) + sb.buffer.buffer_len));
  329.         return TRUE;
  330.     }
  331.     return FALSE;
  332. }
  333. #endif
  334.